package BUS;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
import java.util.Vector;

import org.ietf.jgss.Oid;

import BUS.CommandFromClient.COMMAND_ID;
import BUS.DataPackageFromServer.DATA_ID;
import DAO.RecordDAO;
import DTO.DatabaseDTO;
import DTO.RecordDTO;
import DTO.TableDTO;
import GUI.MainScreen;

public class Server {
	public static String IP_SERVER = "127.0.0.1";
	public static int PORT_SERVER = 3200;
	private ServerSocket _serverSocket;
	private Vector<Socket> _lstClientSocket;
	private int _nClientSocket;

	public void SetPort(int port) {
		this.PORT_SERVER = port;
	}

	public Server() {
		try {
			_serverSocket = new ServerSocket(PORT_SERVER);
			_lstClientSocket = new Vector<Socket>();
			_nClientSocket = 0;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void AllowConnect() {
		new ConnectionThread().start();
	}

	private class ConnectionThread extends Thread {
		@Override
		public void run() {
			try {
				while (true) {
					Socket clientSocket = _serverSocket.accept();
					new InteractionThread(clientSocket).start();
					_lstClientSocket.add(clientSocket);
					_nClientSocket++;
					Thread.sleep(200);
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private class InteractionThread extends Thread {

		private Socket _clientSocket;
		private ObjectInputStream _ois;
		private ObjectOutputStream _oos;

		public InteractionThread(Socket clientSocket) {
			_clientSocket = clientSocket;
			try {
				_oos = new ObjectOutputStream(clientSocket.getOutputStream());
				_ois = new ObjectInputStream(clientSocket.getInputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			try {
				while (true) {
					CommandFromClient clientCommand = RecieveCommand();
					if (clientCommand.get_ID() == COMMAND_ID.EXIT)
						break;
					DataPackageFromServer result = ExecuteCommand(clientCommand);
					SendResultToClient(result);
					Thread.sleep(100);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		private void SendResultToClient(DataPackageFromServer result) {
			// TODO Auto-generated method stub
			try {
				_oos.writeObject(result);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		private DataPackageFromServer ExecuteCommand(
				CommandFromClient clientCommand) {
			if (clientCommand == null) {
				return null;
			}
			DataPackageFromServer result = null;
			String content = clientCommand.get_content();
			QueryProccessor queryProcessor = new QueryProccessor(content);
			try {
				TableDTO table = (TableDTO) queryProcessor.excuteQuey();
				if (table != null
						|| clientCommand.get_ID() != COMMAND_ID.SELECT)
					result = new DataPackageFromServer(DATA_ID.RESULT, table,
							"SUCCESS");
				else
					result = new DataPackageFromServer(DATA_ID.MESSAGE, null,
							"SUCCESS: Table have no record");
			} catch (Exception e) {
				// TODO: handle exception
				// Send error info for client
				e.printStackTrace();
				result = new DataPackageFromServer(DATA_ID.MESSAGE, null,
						"FAIL: " + e.getMessage());
			}
			return result;
			// switch (clientCommand.get_ID()) {
			// case CREATE:
			// if (queryProcessor.isValidCreateCommand(content))
			// queryProcessor.CreateDatabase(content);
			// break;
			// case INSERT:
			// //if (isValidInsertCommand(content))
			// try{
			// queryProcessor.InsertToDatabase(content);
			// }catch(Exception ex)
			// {
			// //Invalid Insert Command
			// }
			// break;
			// case UPDATE:
			// break;
			// case DELETE:
			// break;
			// case SELECT:
			// break;
			// }
		}

		private CommandFromClient RecieveCommand() {
			CommandFromClient result = null;
			try {
				result = (CommandFromClient) _ois.readObject();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return result;
		}
	}

}
